//
//  UIImage+HFAdd.m
//  HeFanLIVE
//
//  Created by Shelin on 16/12/13.
//
//

#import "UIImage+HFAdd.h"
#import <ImageIO/ImageIO.h>
#import <Accelerate/Accelerate.h>

@implementation UIImage (HFAdd)

#pragma mark - public ---


+ (UIImage *)roundRectangleWithRadius:(CGFloat)radius
                                 size:(CGSize)size
                                color:(UIColor *)color {
    
    //开启图形上下文
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    //绘制颜色区域
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:radius];
    
    [color setFill];
    
    [path fill];
    
    //从图形上下文获取图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //关闭图形上下文
    UIGraphicsEndImageContext();
    
    return newImage;
}

+ (UIImage *)roundRectangleBorderWithRadius:(CGFloat)radius
                                 size:(CGSize)size
                                borderColor:(UIColor *)borderColor {
    
    //开启图形上下文
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    //绘制颜色区域
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:radius];
    
    [borderColor setStroke];
    
    [path stroke];
    
    //从图形上下文获取图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //关闭图形上下文
    UIGraphicsEndImageContext();
    
    return newImage;
}



//将颜色转化成图片

+ (UIImage*)createImageWithColor:(UIColor*)color {
    
    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}



+(UIImage *)cereateSizeImageWithImage:(UIImage *)scImg limitSize:(CGSize)limitSize
{
    if (scImg.size.width <= limitSize.width && scImg.size.height <= limitSize.height) {
        return scImg;
    }
    CGSize thumbSize;
    if (scImg.size.width / scImg.size.height > limitSize.width / limitSize.height) {
        thumbSize.width = limitSize.width;
        thumbSize.height = limitSize.width / scImg.size.width * scImg.size.height;
    }
    else {
        thumbSize.height = limitSize.height;
        thumbSize.width = limitSize.height / scImg.size.height * scImg.size.width;
    }
    UIGraphicsBeginImageContext(thumbSize);
    [scImg drawInRect:(CGRect){CGPointZero,thumbSize}];
    UIImage *thumbImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return thumbImg;
}


+(nullable UIImage *)bg_imageWithData:(nonnull NSData *)imageData{
    if (!imageData) {
        return nil;
    }
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
    size_t count = CGImageSourceGetCount(source);
    UIImage *animatedImage;
    if (count <= 1) {
        animatedImage = [[UIImage alloc] initWithData:imageData];
    }
    else {
        NSMutableArray *images = [NSMutableArray array];
        NSTimeInterval duration = 0.0f;
        for (size_t i = 0; i < count; i++) {
            CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
            duration += [self bp_frameDurationAtIndex:i source:source];
            [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
            CGImageRelease(image);
        }
        if (!duration) {
            duration = (1.0f / 10.0f) * count;
        }
        animatedImage = [UIImage animatedImageWithImages:images duration:duration];
    }
    CFRelease(source);

    return animatedImage;
}

+ (float)bp_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
    float frameDuration = 0.1f;
    CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
    NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
    NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];

    NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
    if (delayTimeUnclampedProp) {
        frameDuration = [delayTimeUnclampedProp floatValue];
    }
    else {

        NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
        if (delayTimeProp) {
            frameDuration = [delayTimeProp floatValue];
        }
    }

    if (frameDuration < 0.011f) {
        frameDuration = 0.100f;
    }

    CFRelease(cfFrameProperties);
    return frameDuration;
}

+ (UIImage *)blurImage:(UIImage *)image blur:(CGFloat)blur
{
    // 模糊度越界
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 40);
    boxSize = boxSize - (boxSize % 2) + 1;
    CGImageRef img = image.CGImage;
    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;
    void *pixelBuffer;
    //从CGImage中获取数据
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    //设置从CGImage获取对象的属性
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);

    if (inBitmapData) {
        inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
    }

    pixelBuffer = malloc(CGImageGetBytesPerRow(img) *
                         CGImageGetHeight(img));

    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");

    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);

    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

    if (error) {
        NSLog(@"error from convolution %ld", error);
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(
                                             outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);

    free(pixelBuffer);
    CFRelease(inBitmapData);

    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageRef);

    return returnImage;
}

/**
 *  返回一张可以随意拉伸不变形的图片
 *  @param name 图片名字
 */
+ (UIImage *)resizableImage:(NSString *)name
{
    UIImage *normal = [UIImage imageNamed:name];
    CGFloat w = normal.size.width * 0.5;
    CGFloat h = normal.size.height * 0.5;
    // 拉伸图片
    //        [normal stretchableImageWithLeftCapWidth:<#(NSInteger)#> topCapHeight:<#(NSInteger)#>];
    //        [normal resizableImageWithCapInsets:<#(UIEdgeInsets)#> resizingMode:<#(UIImageResizingMode)#>];
    return [normal resizableImageWithCapInsets:UIEdgeInsetsMake(h, w, h, w)];
}

//拼接
+(UIImage *)combineWithImages:(NSArray *)images orientation:(ImageCombineType)orientation{
    NSMutableArray *sizeArray = [[NSMutableArray alloc] init];
    CGFloat maxHeight = 0, maxWidth = 0;
    for (id image in images) {
//        if([image isKindOfClass:[UIImage class]]){
        CGSize size = ((UIImage *)image).size;
        if(orientation == ImageCombineHorizental){//横向
            maxWidth += size.width;
            maxHeight = (size.height > maxHeight) ? size.height : maxHeight;
        }
        else{
            maxHeight += size.height;
            maxWidth = (size.width > maxWidth) ? size.width : maxWidth;
        }
        [sizeArray addObject:[NSValue valueWithCGSize:size]];
//        }
    }

    CGFloat lastLength = 0;//记录上一次的最右或者最下边值
    UIGraphicsBeginImageContext(CGSizeMake(maxWidth, maxHeight));
    for (int i = 0; i < sizeArray.count; i++){
        CGSize size = [[sizeArray objectAtIndex:i] CGSizeValue];
        CGRect currentRect;
        if(orientation == ImageCombineHorizental){//横向
            currentRect = CGRectMake(lastLength, (maxHeight - size.height) / 2.0, size.width, size.height);
            [[images objectAtIndex:i] drawInRect:currentRect];
            lastLength = CGRectGetMaxX(currentRect);
        }
        else{
            currentRect = CGRectMake((maxWidth - size.width) / 2.0, lastLength, size.width, size.height);
            [[images objectAtIndex:i] drawInRect:currentRect];
            lastLength = CGRectGetMaxY(currentRect);
        }
    }
    UIImage* combinedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return combinedImage;
}


//局部收缩
- (UIImage *)shrinkImageWithCapInsets:(UIEdgeInsets)capInsets actualSize:(CGSize)actualSize{//默认拉伸好了 暂时不处理平铺的情况
    //一块区域  分为三块  两边不变 中间收缩
    UIImage *newAllImage = self;
    //如果横向变短了  处理横向
    if(actualSize.width < self.size.width){
        NSMutableArray *imageArray = [[NSMutableArray alloc] init];
        //左边:
        if(capInsets.left > 0){
            UIImage *leftImage = [newAllImage clipImageWithClipRect:CGRectMake(0, 0, capInsets.left, newAllImage.size.height)];
            [imageArray addObject:leftImage];
        }
        //中间: 缩短
        CGFloat shrinkWidth = actualSize.width - capInsets.left - capInsets.right;//需要缩到的距离
        if(shrinkWidth > 0){
            UIImage *centerImage = [newAllImage clipImageWithClipRect:CGRectMake(capInsets.left, 0, newAllImage.size.width - capInsets.left - capInsets.right, newAllImage.size.height)];
            centerImage = [centerImage scaleImageToSize:CGSizeMake(shrinkWidth, newAllImage.size.height)];
            [imageArray addObject:centerImage];
        }
        //右边:
        if(capInsets.right > 0){
            UIImage *rightImage = [newAllImage clipImageWithClipRect:CGRectMake(newAllImage.size.width - capInsets.right, 0, capInsets.right, newAllImage.size.height)];
            [imageArray addObject:rightImage];
        }

        //拼接
        if(imageArray.count > 0){
            newAllImage = [UIImage combineWithImages:imageArray orientation:ImageCombineHorizental];
            if(actualSize.height >= self.size.height){
                return newAllImage;
            }//否则继续纵向处理
        }
    }

    //如果纵向变短了 处理纵向(在横向处理完的基础上)
    if(actualSize.height < self.size.height){
        NSMutableArray *imageArray = [[NSMutableArray alloc] init];
        //上边:
        if(capInsets.top > 0){
            UIImage *topImage = [newAllImage clipImageWithClipRect:CGRectMake(0, 0, self.size.width,capInsets.top)];
            [imageArray addObject:topImage];
        }
        //中间: 缩短
        CGFloat shrinkHeight = actualSize.height - capInsets.top - capInsets.bottom;//需要缩到的距离
        if(shrinkHeight > 0){
            UIImage *centerImage = [newAllImage clipImageWithClipRect:CGRectMake(0, capInsets.top, newAllImage.size.width,newAllImage.size.height - capInsets.bottom - capInsets.top)];
            centerImage = [centerImage scaleImageToSize:CGSizeMake(newAllImage.size.width,shrinkHeight)];
            [imageArray addObject:centerImage];
        }
        //下边:
        if(capInsets.bottom > 0){
            UIImage *bottomImage = [newAllImage clipImageWithClipRect:CGRectMake(0, newAllImage.size.height - capInsets.bottom, newAllImage.size.width,capInsets.bottom)];
            [imageArray addObject:bottomImage];
        }

        //拼接
        if(imageArray.count > 0){
            newAllImage = [UIImage combineWithImages:imageArray orientation:ImageCombineVertical];
            return newAllImage;
        }
    }

    return nil;
}
















#pragma mark - private ------

//按照一定大小缩放图片
-(UIImage *)scaleImageToSize:(CGSize)size{
    UIGraphicsBeginImageContext(size);//设定大小
    [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *scaleImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaleImage;
}

//裁剪图片
-(UIImage *)clipImageWithClipRect:(CGRect)clipRect{
    CGImageRef clipImageRef = CGImageCreateWithImageInRect(self.CGImage, clipRect);
    UIGraphicsBeginImageContext(clipRect.size);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, clipRect, clipImageRef);
    UIImage *clipImage = [UIImage imageWithCGImage :clipImageRef];

    UIGraphicsEndImageContext();

    return clipImage;
}








@end
